package com.txby.core.util;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.output.FileWriterWithEncoding;
import org.junit.Test;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;

import com.google.common.collect.Maps;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
 * FreemarkerUtil工具类
* @ClassName: FreemarkerUtil 
* @Description: TODO （描述）
* @author 作者 jacking
* @date 2016-7-5 上午9:52:21
 */
public class FreemarkerUtil {
	public static String rootClassFtlPath="classpath:/template";
	private static FreemarkerUtil util;
	private static Configuration cfg;
	private FreemarkerUtil() {
	}
	/**
	 * 获class 模版路径的工具对象
	* @Title: getInstance 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param classFtlPath
	* @param @return
	* @param @throws IOException    设定文件 
	* @return FreemarkerUtil    返回类型 
	* @throws
	 */
	public static synchronized FreemarkerUtil getInstance(String  classFtlPath) throws IOException {
		if(util==null) {
			cfg = new Configuration();
			if(null!=classFtlPath&&!"".equals(classFtlPath)) {
				cfg.setClassForTemplateLoading(FreemarkerUtil.class, classFtlPath);  //从class获取相对路径
//			  cfg.setDirectoryForTemplateLoading(new File(pname));//绝对路径
			}
			cfg.setDefaultEncoding("utf-8");
			util = new FreemarkerUtil();
		}
		return util;
	}
	/**
	 * 清除单例工具对象
	* @Title: cleanFreemarkerUtil 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param     设定文件 
	* @return void    返回类型 
	* @throws
	 */
	public static void cleanFreemarkerUtil() {
		util=null;
	}
	/**
	 *  获class 模版路径的工具对象
	* @Title: getInstanceDirPath 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param pname
	* @param @return
	* @param @throws IOException    设定文件 
	* @return FreemarkerUtil    返回类型 
	* @throws
	 */
	public static  synchronized FreemarkerUtil  getInstanceDirPath(String fileDirPath) throws IOException {
		if(util==null) {
			cfg = new Configuration();
			if(null!=fileDirPath&&!"".equals(fileDirPath)) {
				cfg.setDirectoryForTemplateLoading(new File(fileDirPath));//绝对路径
//			cfg.setClassForTemplateLoading(FreemarkerUtil.class, pname);  //从class获取相对路径
			}
			cfg.setDefaultEncoding("utf-8");
			util = new FreemarkerUtil();
		}
		return util;
	}
	/**
	 * 根据模版名称从配置的路径中
	* @Title: getTemplate 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param fname
	* @param @return    设定文件 
	* @return Template    返回类型 
	* @throws
	 */
	private Template getTemplate(String ftlName) {
		try {
			return cfg.getTemplate(ftlName);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 通过标准输出流输出模板的结果
	 * @param root 数据对象
	 * @param fname 模板文件
	 */
	public void sprint(Map<String,Object> root,String fname) {
		try {
			Template template  = getTemplate(fname);
			template.setEncoding("utf-8");
			template.process(root, new PrintWriter(System.out));
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 基于文件的输出
	 * @param root
	 * @param fname
	 * @param outpath
	 */
	public void fprint(Map<String,Object> root,String fname,String outpath) {
		try {
			File filePath = new File(outpath).getParentFile();
			if(!filePath.exists()){
				filePath.mkdirs();
			}
			Template template  = getTemplate(fname);
			if(template!=null){
				template.setEncoding("utf-8");
				template.process(root, new FileWriterWithEncoding(outpath, "utf-8"));
			}else{
				System.out.println("null");
			}
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	

	/**
	 *  根据flt模版将数据转String输出
	* @Title: renderString 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param templateString
	* @param @param model
	* @param @return    设定文件 
	* @return String    返回类型 
	* @throws
	 */
	public static String renderString(String templateString, Map<?, ?> model) {
		try {
			StringWriter result = new StringWriter();
			Template t = new Template("name", new StringReader(templateString), new Configuration());
			t.process(model, result);
			return result.toString();
		} catch (Exception e) {
		}
		return templateString;
	}
	/**
	 * 根据flt模版将数据转String输出
	* @Title: renderTemplate 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param template
	* @param @param model
	* @param @return    设定文件 
	* @return String    返回类型 
	* @throws
	 */
	public static String renderTemplate(Template template, Map<String,Object> model) {
		try {
			StringWriter result = new StringWriter();
			template.process(model, result);
			return result.toString();
		} catch (Exception e) {
		}
		return null;
	}
   /**
    * 根据class目录获取绝对路径
   * @Title: buildConfiguration 
   * @Description: TODO(这里用一句话描述这个方法的作用) 
   * @param @param directory
   * @param @return
   * @param @throws IOException    设定文件 
   * @return Configuration    返回类型 
   * @throws
    */
	public static Configuration buildConfiguration(String directory) throws IOException {
		Configuration cfg = new Configuration();
		Resource path = new DefaultResourceLoader().getResource(directory);
		cfg.setDirectoryForTemplateLoading(path.getFile());
		return cfg;
	}
	/**
	 * 根据模版名称（预先配置的模版路径）将数据转String输出
	* @Title: getFtlData 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param ftlName
	* @param @param rootFtlPath
	* @param @param model
	* @param @return    设定文件 
	* @return String    返回类型 
	* @throws
	 */
	public static String getFtlData(String ftlName,String rootFtlPath, Map<String,Object> model){
		Configuration cfg;
		Template template = null;
		try {
			if(null!=rootFtlPath&&!"".equals(rootFtlPath)) {
				rootClassFtlPath=rootFtlPath;
			}
			cfg = FreemarkerUtil.buildConfiguration(rootClassFtlPath);
			cfg.setDefaultEncoding("utf-8");
			template = cfg.getTemplate(ftlName);
		} catch (IOException e) {
			e.printStackTrace();
		}
		String result = FreemarkerUtil.renderTemplate(template, model);
		return result;
		
	}
	@Test
	public   void test() throws IOException {
//		// renderString
		Map<String, Object> model = Maps.newHashMap();
//		model.put("userName", "calvin");
//		String result = FreemarkerUtil.renderString("hello ${userName}", model);
//		System.out.println(result);
//		// renderTemplate
		Configuration cfg = FreemarkerUtil.buildConfiguration("classpath:/");
		Template template = cfg.getTemplate("testTemplate.ftl");
		String result2 = FreemarkerUtil.renderTemplate(template, model);
		System.out.println(result2);
		
//		Map<String, String> model = com.google.common.collect.Maps.newHashMap();
//		model.put("userName", "calvin");
//		String result = FreemarkerUtil.renderString("hello ${userName} ${r'${userName}'}", model);
//		System.out.println(result);
	}
	@Test
	public  void test2() throws IOException {
		
		FreemarkerUtil u=getInstance("/ftl");
		
		Map root=new HashMap<String, Object>();
		
		root.put("username", "dd");
		u.sprint(root, "t.ftl");
		
	}
}
